package com.feng.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feng.commonutils.JwtUtils;
import com.feng.commonutils.R;
import com.feng.commonutils.vo.CourseVo;
import com.feng.eduservice.client.OrderClient;
import com.feng.eduservice.client.VodClient;
import com.feng.eduservice.dto.CourseInfoDto;
import com.feng.eduservice.dto.CourseQuery;
import com.feng.eduservice.entity.*;
import com.feng.eduservice.frontvo.CourseFrontVo;
import com.feng.eduservice.frontvo.CourseWebVo;
import com.feng.eduservice.mapper.EduCourseDescriptionMapper;
import com.feng.eduservice.mapper.EduCourseMapper;
import com.feng.eduservice.service.EduChapterService;
import com.feng.eduservice.service.EduCourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.eduservice.service.EduTeacherService;
import com.feng.eduservice.service.EduVideoService;
import com.feng.eduservice.util.BeanCopyUtils;
import com.feng.eduservice.vo.course.CoursePublishVo;
import com.feng.eduservice.vo.course.chapterVo;
import com.feng.servicebase.excecption.GuliException;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author fengge
 * @since 2023-01-17
 */
@Service
@Transactional
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {
    @Autowired
    private EduCourseDescriptionMapper eduCourseDescriptionMapper;
    @Autowired
    private EduCourseMapper eduCourseMapper;
    @Autowired
    private EduVideoService eduVideoService;
    @Autowired
    private EduChapterService eduChapterService;
    @Autowired
    private VodClient vodClient;
    @Autowired
    private EduTeacherService eduTeacherService;
    @Autowired
    private OrderClient orderClient;


    @Override
    public R addCourseInfo(CourseInfoDto courseInfoDto) {
        //向课程表添加课程基本信息
        EduCourse eduCourse = BeanCopyUtils.copyBean(courseInfoDto, EduCourse.class);
        this.save(eduCourse);
        //获取添加之后的课程id
        String cid=eduCourse.getId();
        //2.向课程简介表添加课程简介
        EduCourseDescription eduCourseDescription=new EduCourseDescription();
        eduCourseDescription.setDescription(courseInfoDto.getDescription());
        eduCourseDescription.setId(cid);
        int insert = eduCourseDescriptionMapper.insert(eduCourseDescription);
        if(insert==0){
            throw new GuliException(20001,"添加课程信息失败");
        }
        return R.ok().setMessage("添加信息成功").data("id",cid);
    }

    @Override
    public R getCourseInfo(String courseId) {

        EduCourse eduCourse = this.getById(courseId);
        EduCourseDescription eduCourseDescription = eduCourseDescriptionMapper.selectById(courseId);

        CourseInfoDto courseInfoDto = BeanCopyUtils.copyBean(eduCourse, CourseInfoDto.class);
        courseInfoDto.setDescription(eduCourseDescription.getDescription());
        return R.ok().data("courseInfoVo",courseInfoDto);

    }

    @Override
    public R updateCourseInfo(CourseInfoDto courseInfoDto) {
        EduCourse eduCourse = BeanCopyUtils.copyBean(courseInfoDto, EduCourse.class);
         this.updateById(eduCourse);
         EduCourseDescription eduCourseDescription=new EduCourseDescription();
         eduCourseDescription.setId(courseInfoDto.getId());
         eduCourseDescription.setDescription(courseInfoDto.getDescription());
         eduCourseDescriptionMapper.updateById(eduCourseDescription);
         return R.ok();

    }

    @Override
    public R getPublishCourseInfo(String id) {
        CoursePublishVo coursePublishVo = eduCourseMapper.getPublishCourseInfo(id);
        return R.ok().data("publishCourse",coursePublishVo);

    }

    @Override
    public R publishCourse(String id) {
        EduCourse eduCourse=new EduCourse();
        eduCourse.setId(id);
        eduCourse.setStatus("Normal");
        this.updateById(eduCourse);
        return R.ok();
    }

    @Override
    public R getCourseList(long current, long limit, CourseQuery courseQuery) {
        Page<EduCourse> page=new Page<>(current,limit);
        LambdaQueryWrapper<EduCourse> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.like(!StringUtils.isEmpty(courseQuery.getTitle()),EduCourse::getTitle,courseQuery.getTitle());
        queryWrapper.eq(!StringUtils.isEmpty(courseQuery.getStatus()),EduCourse::getStatus,courseQuery.getStatus());
        queryWrapper.ge(!StringUtils.isEmpty(courseQuery.getBegin()),EduCourse::getGmtCreate,courseQuery.getBegin());
        queryWrapper.le(!StringUtils.isEmpty(courseQuery.getEnd()),EduCourse::getGmtCreate,courseQuery.getEnd());
        queryWrapper.orderByDesc(EduCourse::getGmtCreate) ;
        this.page(page,queryWrapper);
        long total = page.getTotal();
        List<EduCourse> records = page.getRecords();
        Map<String,Object> map=new HashMap();
        map.put("total",total);
        map.put("rows",records);
        return R.ok().data(map);

    }

    @Override
    @Transactional
    public R deleteCourse(String courseId) {
        //1.根据课程id删除小节

         LambdaQueryWrapper<EduVideo> queryWrapper=new LambdaQueryWrapper<>();;
          queryWrapper.eq(EduVideo::getCourseId,courseId);
        List<EduVideo> videolist = eduVideoService.list(queryWrapper);
        List<String> id = videolist.stream().filter(e->{
            //先过滤空id
            return e.getVideoSourceId()!=null;
        }).map(e -> {

            return e.getVideoSourceId();

        }).collect(Collectors.toList());
        //删除小节中对应的视频
        if(id.size()>0) {
            vodClient.deleteBatch(id);
        }
        eduVideoService.remove(queryWrapper);
        //2.根据课程id删除章节
        LambdaQueryWrapper<EduChapter> queryWrapper1=new LambdaQueryWrapper<>();
        queryWrapper1.eq(EduChapter::getCourseId,courseId);
        eduChapterService.remove(queryWrapper1);
        //3.删除描述信息
        LambdaQueryWrapper<EduCourseDescription> queryWrapper2=new LambdaQueryWrapper<>();
        queryWrapper2.eq(EduCourseDescription::getId,courseId);
        //删除课程
        this.removeById(courseId);
        return R.ok().message("删除课程信息成功");
    }

    @Override
    public R getFrontCourseList(long page, long limit, CourseFrontVo courseFrontVo) {
        Page<EduCourse> pageCourse=new Page<>(page,limit);
        LambdaQueryWrapper<EduCourse> queryWrapper=new LambdaQueryWrapper<>();
        //查询一级分类
        queryWrapper.eq(!StringUtils.isEmpty(courseFrontVo.getSubjectParentId()),EduCourse::getSubjectParentId,courseFrontVo.getSubjectParentId());
        //查询二级分类
        queryWrapper.eq(!StringUtils.isEmpty(courseFrontVo.getSubjectId()),EduCourse::getSubjectId,courseFrontVo.getSubjectId());
        //查询讲师
        queryWrapper.eq(!StringUtils.isEmpty(courseFrontVo.getTeacherId()),EduCourse::getTeacherId,courseFrontVo.getTeacherId());
       //按销量排序
        queryWrapper.orderByDesc(!StringUtils.isEmpty(courseFrontVo.getBuyCountSort()),EduCourse::getBuyCount);
       //按价格排序
        queryWrapper.orderByDesc(!StringUtils.isEmpty(courseFrontVo.getPriceSort()), EduCourse::getPrice);
        //按创建时间排序
        queryWrapper.orderByDesc(!StringUtils.isEmpty(courseFrontVo.getGmtCreateSort()),EduCourse::getGmtCreate);
        queryWrapper.eq(EduCourse::getStatus,"Normal");
        baseMapper.selectPage(pageCourse,queryWrapper);

        long total = pageCourse.getTotal();//总记录数
        List<EduCourse> courseList = pageCourse.getRecords();//数据集合
        long size = pageCourse.getSize();//每页记录数
        long current = pageCourse.getCurrent();//当前页
        long pages = pageCourse.getPages();//总页数
        boolean hasPrevious = pageCourse.hasPrevious();//是否有上一页
        boolean hasNext = pageCourse.hasNext();//是否有下一页

        HashMap<String, Object> map = new HashMap<>();
        map.put("total",total);
        map.put("list",courseList);
        map.put("size",size);
        map.put("current",current);
        map.put("pages",pages);
        map.put("hasPrevious",hasPrevious);
        map.put("hasNext",hasNext);
        return R.ok().data(map);
    }

    @Override
    public R getFrontCourseInfo(String courseId, HttpServletRequest request) {
        //根据课程id，编写sql语句查询课程信息
         CourseWebVo courseWebVo=this.getBaseCourseInfo(courseId);

       //浏览 数量+1
        EduCourse course = this.getById(courseWebVo.getId());
        course.setViewCount(course.getViewCount()+1);
        this.updateById(course);
        //根据课程id查询章节和小节
        List<chapterVo> chapterVideo = eduChapterService.getChapterVideo(courseId);
        String memberId = JwtUtils.getMemberIdByJwtToken(request);
        if(StringUtils.isEmpty(memberId)){
            return R.ok().data("courseWebVo",courseWebVo).data("chapterVideoList",chapterVideo).data("isBuy",false);

        }
        //根据课程id和用户id查询当前课程是否已经支付过
        Boolean buyCourse = orderClient.getCourseBuy(courseId, memberId);
        return R.ok().data("courseWebVo",courseWebVo).data("chapterVideoList",chapterVideo).data("isBuy",buyCourse);

    }

    @Override
    public CourseWebVo  getBaseCourseInfo(String courseId) {
        return baseMapper.getBaseCourseInfo(courseId);
    }

    @Override
    public CourseVo getCourseInfos(String courseId) {
        EduCourse eduCourse = this.getById(courseId);
        CourseVo courseVo = BeanCopyUtils.copyBean(eduCourse, CourseVo.class);
        //根据讲师id查询讲师信息

        EduTeacher eduTeacher = eduTeacherService.getById(eduCourse.getTeacherId());
        //设置对应的信息
        courseVo.setTeachername(eduTeacher.getName());
        return courseVo;
    }

    @Override
    public R updateCourseCount(String courseId) {
        EduCourse course = this.getById(courseId);
        Long buyCount = course.getBuyCount();
        course.setBuyCount(buyCount+1);
        this.updateById(course);
        return R.ok();
    }


}
